{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 利用Python进行数据分析 chapter4 NumPy基础\n",
    "\n",
    "> 2023/1/25"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### jupyter && vscode 快捷键\n",
    "\n",
    "##### Cell命令模式目前支持的Jupyter Notebook快捷\n",
    "* Enter : 转入编辑模式\n",
    "* Shift-Enter : 运行本单元，选中或插入（最后一个Cell的时候）下个单元\n",
    "* Ctrl-Enter : 运行本单元\n",
    "* Alt-Enter : 运行本单元，在其下插入新单元\n",
    "* Y : 单元转入代码状态\n",
    "* M :单元转入markdown状态 （目前尚不支持R 原生状态）\n",
    "* Up : 选中上方单元\n",
    "* K : 选中上方单元\n",
    "* Down : 选中下方单元\n",
    "* J : 选中下方单元\n",
    "* A : 在上方插入新单元\n",
    "* B : 在下方插入新单元\n",
    "* D,D : 删除选中的单元\n",
    "* L : 转换行号\n",
    "* Shift-Space : 向上滚动\n",
    "* Space : 向下滚动\n",
    " \n",
    "\n",
    "##### Cell编辑模式下支持的Vscode快捷键（只描述与编辑相关的那些快捷键）\n",
    "* Ctrl + X ：剪切/剪切行（空选定）\n",
    "* Ctrl + C : 复制/复制行（空选定）\n",
    "* Ctrl + Delete / Backspace :删除右边、左边的字\n",
    "* Alt + ↑ / ↓ :向上/向下移动行\n",
    "* Shift + Alt + ↓ / ↑ : 向上/向下复制行\n",
    "* Ctrl + Shift + K : 删除行\n",
    "* Ctrl + Shift + \\ : 跳到匹配的括号\n",
    "* Ctrl + ] / [ : 缩进/突出行\n",
    "* Ctrl + ← / → : 光标到字首/字尾\n",
    "* Ctrl + / : 切换行注释\n",
    "* Shift + Alt + A : 切换块注释\n",
    "* Ctrl + H : 查找/替换\n",
    "* Vscode的查找快捷键 Ctrl + F 目前在Cell里不能用，但是替换快捷键可以使用，因此可以替代原本的查找功能"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 基本对象ndarray\n",
    "\n",
    "#### Attribute\n",
    "* data.shape 表示各个维度大小的**元组**\n",
    "* data.dtype 数组类型\n",
    "\n",
    "#### Constructor\n",
    "![img](./img/p1.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### ndarray和标量\n",
    "    \n",
    "矢量化进行批量运算\n",
    "    \n",
    "大小相等的数组间的算术运算会被运用到元素级别\n",
    "\n",
    "比较运算也会被应用到元素级别"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "origin arr\t [0 1 2 3 4]\n",
      "arr+arr\t\t [0 2 4 6 8]\n",
      "arr*3\t\t [ 0  3  6  9 12]\n",
      "arr < 3\t\t [ True  True  True False False]\n"
     ]
    }
   ],
   "source": [
    "arr = np.arange(5)\n",
    "print('origin arr\\t',arr)\n",
    "print('arr+arr\\t\\t',arr+arr)\n",
    "print('arr*3\\t\\t',arr*3)\n",
    "print('arr < 3\\t\\t',arr<3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 索引 切片\n",
    "\n",
    "##### 一维数组的切片索引同List"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'map'> <map object at 0x000001AC9FC61608>\n",
      "<class 'list'> [0, 1, 4, 9, 16]\n",
      "ndarray切片上标量值的改变会反映到整个原始数组，所以切片并不是复制的，这是广播\n",
      "原始的 [0 1 2 3 4],切片后赋值 [99  1  2  3  4]\n",
      "显式的复制操作可以使用arr[:3].copy()\n"
     ]
    }
   ],
   "source": [
    "arr = np.arange(5)\n",
    "## review map && lambda\n",
    "## python3 map函数返回的是迭代器，python2 map直接返回list\n",
    "new_arr = map(lambda x:x**2,arr) \n",
    "print(type(new_arr),new_arr)\n",
    "new_arr = list(new_arr)\n",
    "print(type(new_arr),new_arr)\n",
    "\n",
    "print('ndarray切片上标量值的改变会反映到整个原始数组，所以切片并不是复制的，这是广播')\n",
    "print('原始的',arr,end=',')\n",
    "arr_1 = arr[:3]\n",
    "arr_1[0]=99\n",
    "print('切片后赋值',arr)\n",
    "\n",
    "print('显式的复制操作可以使用arr[:3].copy()')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 高维ndarray的切片和索引"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'numpy.ndarray'>\n",
      "[[1 2 3]\n",
      " [2 4 6]\n",
      " [3 6 9]]\n"
     ]
    }
   ],
   "source": [
    "\n",
    "arr = np.array([[i*j for i in range(1,4)] for j in range(1,4)])\n",
    "print(type(arr))\n",
    "print(arr)\n",
    "\n",
    "## 索引 两种方式等价\n",
    "# arr[1][2]\n",
    "# arr[1,2]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 切片索引\n",
    "\n",
    "在高维度的ndarray上，可以在一个或者多个轴向上进行切片，也可以将整数索引和切片进行混合\n",
    "\n",
    "对切片表达式的赋值操作也会被广播到整个选区\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "多个轴上进行切片\n",
      "[[2 3]\n",
      " [4 6]]\n",
      "整数索引和切片混合，得到低维度的切片\n",
      "[2 4]\n",
      ": 表示全部\n",
      "[[1 2]\n",
      " [2 4]\n",
      " [3 6]]\n"
     ]
    }
   ],
   "source": [
    "print('多个轴上进行切片',arr[:2,1:],sep='\\n',)\n",
    "print('整数索引和切片混合，得到低维度的切片',arr[1,:2],sep='\\n')\n",
    "print(': 表示全部',arr[:,:2],sep='\\n')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### bool型索引\n",
    "ndarray中 比较运算符的运算也是**矢量化**的，操作后是得到的一个bool型的ndarray\n",
    "\n",
    "使用生成的bool型ndarray可以作为**数组索引**，但需要保证俩数组长度一致"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "bool运算 [ True  True  True False False]\n",
      "bool数组用于索引 [0 1 4]\n",
      "使用bool数组进行索引修改原数组 [100 100 100   3   4]\n"
     ]
    }
   ],
   "source": [
    "arr = np.arange(5)\n",
    "print('bool运算',arr<3)\n",
    "arr_2 = np.array([i*i for i in range(5)])\n",
    "print('bool数组用于索引',arr_2[arr<3])\n",
    "\n",
    "arr[arr<3]=100\n",
    "print('使用bool数组进行索引修改原数组',arr)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 数组转置和轴对换\n",
    "\n",
    "`arr.reshape()`可以对ndarray进行形状变换"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "reshape function\n",
      "[[ 0  1  2  3  4]\n",
      " [ 5  6  7  8  9]\n",
      " [10 11 12 13 14]]\n",
      "arr.T\n",
      "[[ 0  5 10]\n",
      " [ 1  6 11]\n",
      " [ 2  7 12]\n",
      " [ 3  8 13]\n",
      " [ 4  9 14]]\n",
      "np.dot\n",
      "[[ 30  80 130]\n",
      " [ 80 255 430]\n",
      " [130 430 730]]\n"
     ]
    }
   ],
   "source": [
    "arr = np.arange(15).reshape((3,5))\n",
    "print('reshape function',arr,sep='\\n')\n",
    "print('arr.T',arr.T,sep='\\n')\n",
    "\n",
    "print('np.dot',arr.dot(arr.T),sep='\\n')"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 使用ndarray进行数据处理\n",
    "\n",
    "常用函数\n",
    "* sum 对全部元素或者**轴向**元素求和。\n",
    "* mean 算术均值\n",
    "* std,var 标准差和方差\n",
    "* min,max 最大值和最小值\n",
    "* argmin,argmax 最大元素和最小元素的**索引**\n",
    "* sort 排序\n",
    "* unique 返回 唯一值并排序\n",
    "* union1d 并集\n",
    "* intersect1d 交集，公共元素"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  },
  "vscode": {
   "interpreter": {
    "hash": "3c874ee3d65450ef899cacaa06bdca40f9e4450c5e631a94911db3215dbda5b8"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
